<!--<!DOCTYPE html>-->
<!--<html lang="zh-CN">-->
<!--<head>-->
<!--    <meta charset="viewport" content="width=device-width, initial-scale=1.0">-->
<!--    <meta charset="UTF-8">-->
<!--    <title>需求发布平台</title>-->
<!--    <link rel="stylesheet" href="publisher/css/base/reset.css">-->
<!--    <link rel="stylesheet" href="publisher/css/components/navbar.css">-->
<!--    <link rel="stylesheet" href="publisher/css/components/editor.css">-->
<!--    <link rel="stylesheet" href="publisher/css/components/maintenance.css">-->
<!--    <link rel="stylesheet" href="publisher/css/components/messages.css">-->
<!--    <link rel="stylesheet" href="publisher/css/main.css">-->
<!--    &lt;!&ndash; 添加jsMind样式 &ndash;&gt;-->
<!--    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jsmind/style/jsmind.css">-->
<!--    <style>-->
<!--        .generate-mindmap-btn {-->
<!--            background-color: #4CAF50;-->
<!--            color: white;-->
<!--            border: none;-->
<!--            padding: 8px 16px;-->
<!--            text-align: center;-->
<!--            text-decoration: none;-->
<!--            display: inline-block;-->
<!--            font-size: 14px;-->
<!--            margin: 10px 0;-->
<!--            cursor: pointer;-->
<!--            border-radius: 4px;-->
<!--        }-->
<!--        .generate-mindmap-btn:hover {-->
<!--            background-color: #45a049;-->
<!--        }-->
<!--        .mindmap-container {-->
<!--            height: calc(100% - 80px);-->
<!--            border: 1px solid #ddd;-->
<!--            border-radius: 4px;-->
<!--        }-->
<!--    </style>-->
<!--</head>-->
<!--<body>-->
<!--&lt;!&ndash; 其他HTML内容保持不变 &ndash;&gt;-->
<!--&lt;!&ndash; ... existing code ... &ndash;&gt;-->

<!--&lt;!&ndash; 引入jsMind库 &ndash;&gt;-->
<!--<script src="https://cdn.jsdelivr.net/npm/jsmind/js/jsmind.js"></script>-->
<!--<script src="https://cdn.jsdelivr.net/npm/jsmind/js/jsmind.draggable.js"></script>-->

<!--<script src="publisher/js/app.js"></script>-->
<!--<script>-->
<!--    document.addEventListener('DOMContentLoaded', function() {-->
<!--        const inputDemand = document.getElementById('input-demand');-->
<!--        const confirmSubBtn = document.getElementById('confirmsub-btn');-->
<!--        const demandDescription = document.getElementById('demand-description');-->
<!--        const generateMindmapBtn = document.getElementById('generate-mindmap-btn');-->

<!--        let isWaitingForResponse = false;-->
<!--        let conversationId = "";-->
<!--        let jm = null; // jsMind实例-->

<!--        // 初始化jsMind-->
<!--        function initJsMind() {-->
<!--            if (jm === null) {-->
<!--                const options = {-->
<!--                    container: 'mindmap-container',-->
<!--                    theme: 'primary',-->
<!--                    editable: true,  // 设置为可编辑-->
<!--                    mode: 'full'-->
<!--                };-->
<!--                jm = new jsMind(options);-->

<!--                // 初始化时加载默认思维导图数据-->
<!--                const defaultMindData = {-->
<!--                    meta: {-->
<!--                        name: "product_requirements",-->
<!--                        author: "迷人蛋同志",-->
<!--                        version: "1.0"-->
<!--                    },-->
<!--                    format: "node_tree",-->
<!--                    data: {-->
<!--                        id: "root",-->
<!--                        topic: "产品需求",-->
<!--                        children: [-->
<!--                            {-->
<!--                                id: "reg",-->
<!--                                topic: "用户注册模块",-->
<!--                                children: [-->
<!--                                    { id: "email", topic: "支持邮箱注册" },-->
<!--                                    { id: "captcha", topic: "验证码校验" }-->
<!--                                ]-->
<!--                            },-->
<!--                            {-->
<!--                                id: "browse",-->
<!--                                topic: "商品浏览模块",-->
<!--                                children: [-->
<!--                                    { id: "category", topic: "按分类浏览" },-->
<!--                                    { id: "search", topic: "商品搜索功能" }-->
<!--                                ]-->
<!--                            }-->
<!--                        ]-->
<!--                    }-->
<!--                };-->
<!--                jm.show(defaultMindData);-->
<!--            }-->
<!--        }-->

<!--        // 添加节点函数-->
<!--        function addNode() {-->
<!--            const selectedNode = jm.get_selected_node();-->
<!--            if (!selectedNode) {-->
<!--                alert('请先选择一个节点！');-->
<!--                return;-->
<!--            }-->
<!--            const newId = 'node_' + (new Date().getTime());-->
<!--            const newTopic = prompt("请输入新节点内容：", "新需求点");-->
<!--            if (newTopic) {-->
<!--                jm.add_node(selectedNode, newId, newTopic);-->
<!--            }-->
<!--        }-->

<!--        // 删除节点函数-->
<!--        function removeSelectedNode() {-->
<!--            const selectedNode = jm.get_selected_node();-->
<!--            if (!selectedNode || selectedNode.isroot) {-->
<!--                alert('请选中非根节点');-->
<!--                return;-->
<!--            }-->
<!--            jm.remove_node(selectedNode);-->
<!--        }-->

<!--        // 保存结构化数据函数-->
<!--        function save() {-->
<!--            const mindJson = jm.get_data();-->
<!--            console.log('结构化数据：', JSON.stringify(mindJson, null, 2));-->
<!--            alert("控制台已输出结构化数据");-->
<!--            // 可通过 AJAX 提交 mindJson 到后端-->
<!--        }-->

<!--        // 显示加载指示器-->
<!--        function showLoadingIndicator() {-->
<!--            // 在需求描述区域显示加载中提示-->
<!--            demandDescription.value = "正在生成需求描述，请稍候...";-->
<!--            demandDescription.disabled = true;-->
<!--        }-->

<!--        // 移除加载指示器-->
<!--        function removeLoadingIndicator() {-->
<!--            demandDescription.disabled = false;-->
<!--        }-->

<!--        // 发送需求到服务器 - 支持流式响应-->
<!--        async function sendDemand(demand) {-->
<!--            // ... existing code ...-->
<!--        }-->

<!--        // 生成思维导图 - 使用与第一个函数相同的数据格式和流式处理-->
<!--        async function generateMindmap() {-->
<!--            try {-->
<!--                const description = demandDescription.value.trim();-->
<!--                if (!description) {-->
<!--                    alert("请先生成需求描述！");-->
<!--                    return;-->
<!--                }-->

<!--                // 显示加载中状态-->
<!--                document.getElementById('mindmap-container').innerHTML = "<div style='text-align:center; padding-top:100px;'>正在生成思维导图...</div>";-->

<!--                // 准备请求数据 - 使用与第一个函数相同的格式-->
<!--                const requestData = {-->
<!--                    query: description,-->
<!--                    user: "mindmap-user-" + Date.now(),-->
<!--                    inputs: {},-->
<!--                    response_mode: "streaming",  // 改为流式响应-->
<!--                    conversation_id: ""  // 思维导图使用独立的会话-->
<!--                };-->

<!--                // 发送请求到xmind接口-->
<!--                const response = await fetch('/api/xmind', {-->
<!--                    method: 'POST',-->
<!--                    headers: {-->
<!--                        'Content-Type': 'application/json'-->
<!--                    },-->
<!--                    body: JSON.stringify(requestData)-->
<!--                });-->

<!--                if (!response.ok || !response.body) {-->
<!--                    throw new Error(`HTTP error! status: ${response.status}`);-->
<!--                }-->

<!--                // 使用与第一个函数相同的流式处理逻辑-->
<!--                const reader = response.body.getReader();-->
<!--                const decoder = new TextDecoder();-->
<!--                let accumulatedAnswer = ""; // 累积的answer内容-->
<!--                let buffer = ""; // 缓冲区用于处理不完整的数据行-->

<!--                while (true) {-->
<!--                    const {done, value} = await reader.read();-->
<!--                    if (done) break;-->

<!--                    // 解码chunk并添加到缓冲区-->
<!--                    buffer += decoder.decode(value, {stream: true});-->

<!--                    // 按行分割数据-->
<!--                    const lines = buffer.split('\n');-->

<!--                    // 保留最后一行（可能不完整）作为缓冲区-->
<!--                    buffer = lines.pop() || '';-->

<!--                    // 处理每一行-->
<!--                    for (const line of lines) {-->
<!--                        const trimmedLine = line.trim();-->

<!--                        // 跳过空行-->
<!--                        if (!trimmedLine) continue;-->

<!--                        // 处理以 "data: " 开头的行-->
<!--                        if (trimmedLine.startsWith('data: ')) {-->
<!--                            const jsonStr = trimmedLine.substring(6); // 移除 "data: " 前缀-->

<!--                            try {-->
<!--                                const data = JSON.parse(jsonStr);-->

<!--                                // 提取answer内容-->
<!--                                if (data.answer) {-->
<!--                                    accumulatedAnswer += data.answer;-->
<!--                                }-->

<!--                                // 可以根据需要处理其他事件类型-->
<!--                                if (data.event) {-->
<!--                                    console.log('思维导图生成事件:', data.event);-->
<!--                                }-->

<!--                            } catch (parseError) {-->
<!--                                console.warn('解析思维导图JSON失败:', parseError, '原始数据:', jsonStr);-->
<!--                            }-->
<!--                        }-->
<!--                    }-->
<!--                }-->

<!--                // 处理缓冲区中剩余的数据-->
<!--                if (buffer.trim()) {-->
<!--                    const trimmedLine = buffer.trim();-->
<!--                    if (trimmedLine.startsWith('data: ')) {-->
<!--                        const jsonStr = trimmedLine.substring(6);-->
<!--                        try {-->
<!--                            const data = JSON.parse(jsonStr);-->
<!--                            if (data.answer) {-->
<!--                                accumulatedAnswer += data.answer;-->
<!--                            }-->
<!--                        } catch (parseError) {-->
<!--                            console.warn('解析思维导图最后数据失败:', parseError);-->
<!--                        }-->
<!--                    }-->
<!--                }-->

<!--                console.log('思维导图流式响应完成，总内容长度:', accumulatedAnswer.length);-->

<!--                // 解析并渲染思维导图-->
<!--                try {-->
<!--                    // 尝试解析JSON字符串-->
<!--                    let mindData;-->
<!--                    try {-->
<!--                        // 直接尝试解析整个响应-->
<!--                        mindData = JSON.parse(accumulatedAnswer);-->
<!--                    } catch (e) {-->
<!--                        // 如果直接解析失败，尝试提取JSON部分-->
<!--                        const jsonMatch = accumulatedAnswer.match(/\{[\s\S]*\}/);-->
<!--                        if (jsonMatch) {-->
<!--                            mindData = JSON.parse(jsonMatch[0]);-->
<!--                        } else {-->
<!--                            throw new Error("无法从响应中提取有效的JSON数据");-->
<!--                        }-->
<!--                    }-->

<!--                    // 初始化jsMind-->
<!--                    initJsMind();-->

<!--                    // 显示思维导图-->
<!--                    jm.show(mindData);-->
<!--                    console.log('思维导图渲染成功');-->

<!--                } catch (parseError) {-->
<!--                    console.error('解析思维导图数据失败:', parseError);-->
<!--                    console.error('响应内容:', accumulatedAnswer);-->
<!--                    document.getElementById('mindmap-container').innerHTML =-->
<!--                        `<div style='color:red; padding:20px;'>-->
<!--                            解析思维导图数据失败: ${parseError.message}<br>-->
<!--                            <details style="margin-top:10px;">-->
<!--                                <summary>查看原始响应</summary>-->
<!--                                <pre style="background:#f5f5f5; padding:10px; white-space:pre-wrap;">${accumulatedAnswer}</pre>-->
<!--                            </details>-->
<!--                         </div>`;-->
<!--                }-->

<!--            } catch (error) {-->
<!--                console.error('生成思维导图错误:', error);-->
<!--                document.getElementById('mindmap-container').innerHTML =-->
<!--                    `<div style='color:red; padding:20px;'>生成思维导图失败: ${error.message}</div>`;-->
<!--            }-->
<!--        }-->

<!--        // 添加控制按钮事件监听器-->
<!--        document.getElementById('mindmap-container').insertAdjacentHTML('afterend', `-->
<!--                <div style="margin-top: 10px;">-->
<!--                    <button onclick="window.addNodeFunc()">添加节点</button>-->
<!--                    <button onclick="window.removeSelectedNodeFunc()">删除选中节点</button>-->
<!--                    <button onclick="window.saveFunc()">保存结构化数据</button>-->
<!--                </div>-->
<!--            `);-->

<!--        // 将函数暴露到全局作用域，以便按钮可以调用-->
<!--        window.addNodeFunc = addNode;-->
<!--        window.removeSelectedNodeFunc = removeSelectedNode;-->
<!--        window.saveFunc = save;-->

<!--        // 确定需求按钮点击事件-->
<!--        confirmSubBtn.addEventListener('click', function () {-->
<!--            const demand = inputDemand.value.trim();-->
<!--            if (demand && !isWaitingForResponse) {-->
<!--                isWaitingForResponse = true;-->
<!--                inputDemand.disabled = true;-->
<!--                confirmSubBtn.disabled = true;-->

<!--                sendDemand(demand);-->
<!--            }-->
<!--        });-->

<!--        // 生成思维导图按钮点击事件-->
<!--        generateMindmapBtn.addEventListener('click', generateMindmap);-->

<!--        // 输入框回车事件-->
<!--        inputDemand.addEventListener('keypress', function (e) {-->
<!--            if (e.key === 'Enter' && e.ctrlKey && inputDemand.value.trim() && !isWaitingForResponse) {-->
<!--                e.preventDefault();-->
<!--                confirmSubBtn.click();-->
<!--            }-->
<!--        });-->

<!--        // 初始化jsMind-->
<!--        initJsMind();-->
<!--    });-->
<!--</script>-->
<!--</body>-->
<!--</html>-->